"""
@个人中心API
"""
import logging
from flask import request, Blueprint
from flask_jwt_extended import create_access_token, get_jwt_identity, jwt_required
import requests
from base.tools.develop_tools import JsonResult, phone_check, rand_num, login_required
from service.api import API
from base.config.service_config import WXClient
from base.notice.authcode_sender import MessageTemplate


blueprint = Blueprint("personal_service", __name__, url_prefix="/personal/")
logger = logging.getLogger("personal_service")


class RoleType:
    ADMIN = "admin"
    PLAYER = "player"
    VIP = "vip"


@blueprint.route("/get_authcode", methods=["GET"])
def get_authcode():
    try:
        request_args = request.args
        phone_num = request_args.get("phone_num")
        api_obj = PersonalApi()
        if not phone_check(phone_num):
            return JsonResult.error("手机号码输入有误,请重新输入！")
        res = api_obj.send_authcode(phone_num=phone_num)
        return JsonResult.ok("获取验证码成功!", res)
    except Exception as e:
        logger.exception(f"获取验证码失败!{str(e)}")
        return JsonResult.error("获取验证码失败!")


@blueprint.route("/wx_login", methods=["POST"])
def wx_login():
    request_args = request.get_json()
    wx_code = request_args.get("wx_code")
    phone_num = request_args.get("phone_num")
    auth_code = request_args.get("auth_code")
    if not all([phone_num, auth_code, wx_code]):
        return JsonResult.error("请正确填入账号以及验证码!")
    try:
        api_obj = PersonalApi()
        if auth_code != api_obj.get_authcode(phone_num=phone_num):
            return JsonResult.error("登录失败!验证码错误")
        # 获取wx用户唯一id
        open_id = api_obj.get_user_openid(wx_code)
        # 第一次登录直接注册
        if not api_obj.get_user_info(user_id=open_id):
            api_obj.add_user(phone_num=phone_num, user_id=open_id)
        access_token = create_access_token(open_id)
        return JsonResult.ok("登录成功!", access_token)
    except Exception as e:
        logger.exception(f"登录失败!{str(e)}")
        return JsonResult.error("登录失败!")


@blueprint.route("/quit", methods=["GET"])
@login_required
def quit():
    try:
        return JsonResult.ok("注销成功!", True)
    except Exception as e:
        logger.error(f"注销失败!{str(e)}")
        return JsonResult.error("注销失败!")


@blueprint.route("/get_user_info", methods=["GET"])
@jwt_required()
def get_user_info():
    try:
        user_id = get_jwt_identity()
        obj = PersonalApi()
        info = obj.get_user_info(user_id=user_id)
        return JsonResult.ok("请求成功!", info)
    except Exception as e:
        logger.error(f"请求失败!{str(e)}")
        return JsonResult.error("请求失败!")


@blueprint.route("/update_user_info", methods=["POST"])
@jwt_required()
def update_user_info():
    try:
        user_id = get_jwt_identity()
        request_args = request.get_json()
        nick_name = request_args.get("nick_name")
        obj = PersonalApi()
        obj.update_user_info(user_id=user_id, nick_name=nick_name)
        return JsonResult.ok("修改成功!", True)
    except Exception as e:
        logger.error(f"修改失败!{str(e)}")
        return JsonResult.error("修改失败!")


class PersonalApi(API):
    def __init__(self) -> None:
        super().__init__()
        self.table = self._mongo["user_info"]

    # 发送验证码
    def send_authcode(self, phone_num):
        auth_code = rand_num()
        self._sender.send(templateID=MessageTemplate.LOGIN_AUTHCODE.value, templatePara=auth_code, phoneNum=phone_num)
        self._redis.write(key=f"{phone_num}_auth_code",
                          value=auth_code, expire=60*5)
        return auth_code

    # 从数据库获取用户信息
    def get_user_info(self, user_id):
        res = self.table.find_one({"user_id": user_id}, {"_id": 0})
        return res

    # 获得验证码
    def get_authcode(self, phone_num):
        return self._redis.read(f"{phone_num}_auth_code")

    def add_user(self, phone_num, user_id):
        self.table.insert_one(
            {
                "phone_num": phone_num,
                "user_id": user_id,
                "integration": 0,
                "level": 0,
                "nick_name": "未知名小猪",
                "role": "player",
                "collect": []
            }
        )

    def get_user_openid(self, code):
        url = WXClient.URL
        app_id = WXClient.APP_ID
        secret = WXClient.APP_KEY
        grant_type = WXClient.GRANT_TYPE
        params = {
            "appid": app_id,
            "secret": secret,
            "js_code": code,
            "grant_type": grant_type
        }
        res = requests.get(url=url, params=params, verify=False)
        return res.json().get("openid")

    def update_user_info(self, user_id, nick_name):
        self.table.update_one({"user_id": user_id}, {
            "$set": {
                "nick_name": nick_name
            }
        })


class UserAPI(API):
    def __init__(self, user_id) -> None:
        super().__init__()
        self.table = self._mongo["user_info"]
        self.user_id = user_id

    def is_admin(self):
        res = self.table.find_one({"user_id": self.user_id}, {"_id": 0})
        if res.get('role') == "admin":
            return True
        return False
